package com.macro.mall.service.impl;

import com.github.pagehelper.PageHelper;
import com.macro.mall.dao.SmsFlashPromotionDao;
import com.macro.mall.dao.SmsFlashPromotionProductRelationDao;
import com.macro.mall.dao.SmsFlashPromotionSessionDao;
import com.macro.mall.dao.SmsFlashPromotionSkuRelationDao;
import com.macro.mall.dto.PmsSkuFlashSum;
import com.macro.mall.dto.SmsFlashPromotionProduct;
import com.macro.mall.mapper.PmsProductAttributeMapper;
import com.macro.mall.mapper.PmsSkuStockMapper;
import com.macro.mall.mapper.SmsFlashPromotionProductRelationMapper;
import com.macro.mall.model.*;
import com.macro.mall.service.SmsFlashPromotionProductRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.beans.Transient;
import java.rmi.server.ServerCloneException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 限时购商品关联管理Service实现类
 * Created by macro on 2018/11/16.
 */
@Service
public class SmsFlashPromotionProductRelationServiceImpl implements SmsFlashPromotionProductRelationService {
    @Autowired
    private SmsFlashPromotionProductRelationMapper relationMapper;
    @Autowired
    private SmsFlashPromotionProductRelationDao relationDao;
    @Autowired
    private SmsFlashPromotionSkuRelationDao smsFlashPromotionSkuRelationDao;
    @Autowired
    private SmsFlashPromotionDao smsFlashPromotionDao;
    @Autowired
    private SmsFlashPromotionSessionDao smsFlashPromotionSessionDao;
    @Autowired
    private PmsSkuStockMapper skuStockMapper;
    @Autowired
    private PmsProductAttributeMapper productAttributeMapper;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Override
    public int create(List<SmsFlashPromotionProductRelation> relationList) {
        for (SmsFlashPromotionProductRelation relation : relationList) {
            relationMapper.insert(relation);
        }
        return relationList.size();
    }

    @Override
    @Transient
    public void update(Long id, SmsFlashPromotionProductRelation relation) {
        relation.setId(id);
        // 查询现有的商品限时购与商品SKU关系
        SmsFlashPromotionProductRelation oldRelation = smsFlashPromotionSkuRelationDao.selectByPrimaryKey(id);
        if (oldRelation == null) {
            throw new RuntimeException("没有该商品限时购与商品SKU关系");
        }
        // 查询限时购场次信息
        SmsFlashPromotionSession flashPromotionSession = smsFlashPromotionSessionDao.selectById(oldRelation.getFlashPromotionSessionId());

        // 查询限时购活动信息
        SmsFlashPromotion flashPromotion = smsFlashPromotionDao.selectById(oldRelation.getFlashPromotionId());

        //比较时间
        compareTime(flashPromotionSession, flashPromotion);

        // 比较活动状态
        compareFlashPromotionStatus(flashPromotion);

        // 判断是否为同一场次
        compareFlashPromotionSessionStatus(flashPromotionSession);

        // 过滤出有效的SKU库存信息
        List<PmsSkuStock> skuStockList = filterValidSkuStocks(relation.getSkuStockList());

        //根据skuId统计出秒杀数量和
        flashSum(skuStockList);

        // 删除旧的SKU关系
        deleteOldSkuRelations(relation, oldRelation);

        // 批量保存新的SKU关系
        smsFlashPromotionSkuRelationDao.insert(oldRelation.getFlashPromotionId(), oldRelation.getFlashPromotionSessionId(), skuStockList);

        // 更新Redis中的预热信息
        updateRedisCache(oldRelation, skuStockList);
    }

    /**
     * 更新Redis缓存的方法
     * @param oldRelation 旧的关联信息
     * @param skuStockList 新的SKU库存信息
 }
     */
    private void updateRedisCache(SmsFlashPromotionProductRelation oldRelation, List<PmsSkuStock> skuStockList) {
        // 遍历新的 SKU 库存信息
        for (PmsSkuStock skuStock : skuStockList) {
            Long skuId = skuStock.getId();
            Integer flashPromotionCount = skuStock.getFlashPromotionCount();

            // 生成 Redis 键
            String redisKey = oldRelation.getFlashPromotionId() + ":" + oldRelation.getFlashPromotionSessionId() + ":" + skuId;

            // 更新或设置 Redis 中的库存信息
            if (flashPromotionCount != null) {
                redisTemplate.opsForValue().set(redisKey, flashPromotionCount.toString());
            } else {
                // 如果库存为 null，可能需要删除 Redis 中的记录
                redisTemplate.delete(redisKey);
            }
        }
    }

    /**
     * 比较时间
     * @param flashPromotionSession flashPromotionSession
     * @param flashPromotion flashPromotion
     */
    private static void compareTime(SmsFlashPromotionSession flashPromotionSession, SmsFlashPromotion flashPromotion) {
        // 获取当前时间和日期
        LocalDate nowDate = LocalDate.now();
        LocalTime nowTime = LocalTime.now();
        // 获取活动开始和结束日期
        LocalDate promotionStartDate = flashPromotion.getStartDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate promotionEndDate = flashPromotion.getEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        // 获取场次开始和结束时间
        LocalTime startTime = flashPromotionSession.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
        LocalTime endTime = flashPromotionSession.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
        // 校验当前日期是否在活动日期段内
        if (!nowDate.isBefore(promotionStartDate) && !nowDate.isAfter(promotionEndDate) && (nowTime.isBefore(startTime) && nowTime.isAfter(endTime))  ) {
            throw new RuntimeException("当前日期在活动日期段内并且时间已经开始了，不能修改");
        }
        // 如果在活动日期段内，再校验时间
        if ((!nowDate.isBefore(promotionStartDate) && !nowDate.isAfter(promotionEndDate)) ) {
            throw new RuntimeException("当前日期在活动日期段内，不能再修改");
        }
    }

    /**
     * 秒杀数量校验
     * @param skuStockList 秒杀商品库存集合
     */
    private void flashSum(List<PmsSkuStock> skuStockList) {
        List<PmsSkuFlashSum> flashPromotionCount = smsFlashPromotionSkuRelationDao.findBySkuIdCount(skuStockList);
        flashPromotionCount.stream()
                .filter(Objects::nonNull)
                .forEach(pmsSkuFlashSum -> {
                    skuStockList.stream()
                            .filter(Objects::nonNull) // 过滤掉 null 的 skuStock
                            .filter(skuStock -> pmsSkuFlashSum.getSkuId() != null && skuStock.getId() != null) // 确保 SKU ID 不为 null
                            .peek(skuStock -> System.out.println("Comparing SKU ID: " + pmsSkuFlashSum.getSkuId() + " with " + skuStock.getId()))
                            .filter(skuStock -> Objects.equals(pmsSkuFlashSum.getSkuId(), skuStock.getId()))
                            .findFirst()
                            .filter(skuStock -> pmsSkuFlashSum.getSum() > skuStock.getStock())
                            .ifPresent(skuStock -> { throw new RuntimeException(pmsSkuFlashSum.getSkuId()+"的库存不足"); });
                });
    }

    /**
     * 校验限时购活动信息
     * @param flashPromotion 限时购活动信息
     */
    private static void compareFlashPromotionStatus(SmsFlashPromotion flashPromotion) {
        //判断限时购活动信息是否是在线状态
        if (flashPromotion.getStatus() != 1) {
            throw new RuntimeException("限时购活动已关闭");
        }
    }

    /**
     * 校验限时购场次信息
     * @param flashPromotionSession 限时购场次信息
     */
    private static void compareFlashPromotionSessionStatus(SmsFlashPromotionSession flashPromotionSession) {
        //判断限时购场次是否是开启
        if (flashPromotionSession.getStatus() != 1) {
            throw new RuntimeException("限时购场次已关闭");
        }
    }
    /**
     * 删除旧的SKU关系
     */
    private void deleteOldSkuRelations(SmsFlashPromotionProductRelation relation, SmsFlashPromotionProductRelation oldRelation) {
        List<PmsSkuStock> flashPromotionSkuRelationList = relation.getSkuStockList();
        if (flashPromotionSkuRelationList != null) {
            for (PmsSkuStock skuStock : flashPromotionSkuRelationList) {
                smsFlashPromotionSkuRelationDao.del(skuStock.getId(),
                        oldRelation.getFlashPromotionId(),
                        oldRelation.getFlashPromotionSessionId());
            }
        }
    }

    /**
     * 过滤出有效的SKU库存信息
     */
    private List<PmsSkuStock> filterValidSkuStocks(List<PmsSkuStock> skuStockList) {
        return skuStockList.stream()
                .filter(skuStock -> skuStock.getFlashPromotionPrice() != null &&
                        skuStock.getFlashPromotionLimit() != null &&
                        skuStock.getFlashPromotionCount() != null)
                .collect(Collectors.toList());
    }

    @Override
    public int delete(Long id) {
        return relationMapper.deleteByPrimaryKey(id);
    }

    @Override
    public SmsFlashPromotionProductRelation getItem(Long id) {
        return relationMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<SmsFlashPromotionProduct> list(Long flashPromotionId, Long flashPromotionSessionId, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        List<SmsFlashPromotionProduct> list = relationDao.getList(flashPromotionId, flashPromotionSessionId);
        for (SmsFlashPromotionProduct smsFlashPromotionProduct : list) {
            //查询商品的sku库存
            PmsSkuStockExample example = new PmsSkuStockExample();
            example.createCriteria().andProductIdEqualTo(smsFlashPromotionProduct.getProductId());
            List<PmsSkuStock> pmsSkuStockList = skuStockMapper.selectByExample(example);
            smsFlashPromotionProduct.setSkuStockList(pmsSkuStockList);

            //
            PmsProductAttributeExample example1 = new PmsProductAttributeExample();
            example1.setOrderByClause("sort desc");
            example1.createCriteria().andProductAttributeCategoryIdEqualTo(smsFlashPromotionProduct.getProduct().getProductAttributeCategoryId()).andTypeEqualTo(0);
            List<PmsProductAttribute> pmsProductAttributes = productAttributeMapper.selectByExample(example1);
            smsFlashPromotionProduct.setProductAttributeList(pmsProductAttributes);
        }
        return list;
    }

    @Override
    public long getCount(Long flashPromotionId, Long flashPromotionSessionId) {
        SmsFlashPromotionProductRelationExample example = new SmsFlashPromotionProductRelationExample();
        example.createCriteria()
                .andFlashPromotionIdEqualTo(flashPromotionId)
                .andFlashPromotionSessionIdEqualTo(flashPromotionSessionId);
        return relationMapper.countByExample(example);
    }
}
